//package java_cup;

/**
 * This abstract class serves as the base class for grammar EmitSymbols (i.e., both
 * terminals and non-terminals). Each SymbolDraft has a name string, and a string
 * giving the type of object that the SymbolDraft will be represented by on the
 * runtime parse stack. In addition, each SymbolDraft maintains a use count in order
 * to detect EmitSymbols that are declared but never used, and an index Count that
 * indicates where it appears in parse tables (index numbers are unique within
 * terminals or non terminals, but not across both).
 *
 * @see java_cup.terminal
 * @see java_cup.non_terminal
 * @version last updated: 7/3/96
 * @author Frank Flannery
 */
public abstract class SymbolDraft {
    /*-----------------------------------------------------------*/
    /*--- Constructor(s) ----------------------------------------*/
    /*-----------------------------------------------------------*/

    /**
     * Full constructor.
     * 
     * @param name the name of the SymbolDraft.
     * @param type a string with the type name.
     */
    public SymbolDraft(String name, String type) {
        /* sanity check */
        if (name == null)
            name = "";

        /* apply default if no type given */
        if (type == null)
            type = "Object";

        _name = name;
        _stackType = type;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Constructor with default type.
     * 
     * @param name the name of the SymbolDraft.
     */
    public SymbolDraft(String nm) : this(nm, null) {
    }

    /*-----------------------------------------------------------*/
    /*--- (Access to) Instance Variables ------------------------*/
    /*-----------------------------------------------------------*/

    /** String for the human readable name of the SymbolDraft. */
    public String _name;

    /** String for the human readable name of the SymbolDraft. */
    public String Name => _name;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** String for the type of object used for the SymbolDraft on the parse stack. */
    public String _stackType;

    /** String for the type of object used for the SymbolDraft on the parse stack. */
    public String StackType => _stackType;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Count of how many times the SymbolDraft appears in AllProdctions. */
    public int _useCount;

    /** Count of how many times the SymbolDraft appears in AllProdctions. */
    public int UseCount => _useCount;

    /** Increment the use count. */
    public void IncreaseUseCount() {
        _useCount++;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Index of this SymbolDraft (terminal or non terminal) in the parse tables. Note:
     * indexes are unique among terminals and unique among non terminals, however, a
     * terminal may have the same index as a non-terminal, etc.
     */
    public int _index;

    /**
     * Index of this SymbolDraft (terminal or non terminal) in the parse tables. Note:
     * indexes are unique among terminals and unique among non terminals, however, a
     * terminal may have the same index as a non-terminal, etc.
     */
    public int Index => _index;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Indicate if this is a non-terminal. Here in the base class we don't know, so
     * this is abstract.
     */
    public abstract bool IsVn { get; }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Convert to a string. */
    /*@Override*/
    public override string ToString() {
        return Name;
    }

    /*-----------------------------------------------------------*/

}
